package com.common;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Environment;
import android.os.StatFs;

import com.loopj.android.http.Base64;
import com.xike.net.NetConstant;
import com.xike.util.MLog;
import com.xike.util.Manager;
import com.xike.util.StringUtil;

public class LocalFileHelper {

	private static Context context;
	private static LocalFileHelper instance;

	/**
	 * 最低存储容量
	 */
	private static final long LOW_STORAGE_THRESHOLD = 1024 * 1024 * 5;
	/**
	 * 缓存文件过期时间(10天)
	 */
	private static final long FILE_EXPIRED_TIME = 10 * 24 * 3600L;

	/**
	 * 保存的url请求结果，有效时间
	 */
	private static final long URL_EXPIRED_TIME = 3600L;

	/**
	 * 网络缓存的根目录
	 */
	public static String CACHE_HOME_PATH = "";

	/**
	 * 图片缓存的目录
	 */
	private static String CACHE_IMAGE_DIR = "/image/";
	/**
	 * apk缓存的目录
	 */
	private static String CACHE_APK_DIR = "/apk/";
	/**
	 * data缓存的目录
	 */
	private static String CACHE_DATA_DIR = "/data/";

	public static SharedPreferences fileSp;
	public static SharedPreferences.Editor fileSpEditor;

	public LocalFileHelper(Context context) {
		this.context = context;
		fileSp = context.getSharedPreferences(NetConstant.SHARED_PREFERENCES_FILECACHE, Context.MODE_PRIVATE);
		fileSpEditor = fileSp.edit();
		initCacheFile();
	}

	public static LocalFileHelper getInstance(Context context) {
		if (instance == null) {
			instance = new LocalFileHelper(context);
		}
		return instance;
	}

	/**
	 * @Description: TODO<文件存在且可用>
	 * @author: wzl
	 * @data: 2014年9月27日 下午5:17:21
	 */
	public boolean fileIsExited(String url) {
		String strMd5Url = StringUtil.MD5(url);
		String fileName = getCACHE_DATA_DIR() + strMd5Url;
		if (fileSp.contains(strMd5Url)) {
			File file = new File(fileName);
			if (System.currentTimeMillis() / 1000 - fileSp.getLong(fileName, 0) < URL_EXPIRED_TIME) {
				if (file.exists() && file.length() > 0) {
					return true;
				}
			}
			file.delete();
			fileSpEditor.remove(strMd5Url).commit();
		}
		return false;
	}

	/**
	 * @Description: TODO<将字符串保存到文件中>
	 * 
	 * @author: wzl
	 * 
	 * @data: 2014年9月27日 下午4:15:23
	 */
	public static boolean writeStringToFile(String url, String content) {
		boolean result = false;
		String strMd5Url = StringUtil.MD5(url);
		String fileName = getCACHE_DATA_DIR() + strMd5Url;
		File file = new File(fileName);
		try {
			if (file.createNewFile()) {
				FileOutputStream fos = new FileOutputStream(file);
				fos.write(content.getBytes("utf-8"));
				fos.close();

				// 文件名称保存在shareperence
				fileSpEditor.putLong(strMd5Url, System.currentTimeMillis() / 1000);
				fileSpEditor.commit();
				result = true;
			}

		} catch (IOException e) {
			e.printStackTrace();
			result = false;
		} finally {
		}
		return result;
	}

	/**
	 * @Description: TODO<从文件中取出字符串>
	 * 
	 * @author: wzl
	 * 
	 * @data: 2014年9月27日 下午4:15:45
	 */
	public static String getContentFromFile(String url) {
		String fileName = getCACHE_DATA_DIR() + StringUtil.MD5(url);
		try {
			FileInputStream fis = new FileInputStream(new File(fileName));
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buf = new byte[1024];
			int len = 0;
			while ((len = fis.read(buf)) != -1) {
				baos.write(buf, 0, len);
			}
			byte[] data = baos.toByteArray();
			String strContent = Base64.encodeToString(data, Base64.DEFAULT);
			fis.close();
			baos.close();
			return strContent;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}

	public static String getCACHE_HOME_PATH() {
		if (null == CACHE_HOME_PATH || CACHE_HOME_PATH.equals("")) {

			String strPackageName = context.getPackageName();
			if (strPackageName.contains(".")) {
				strPackageName = strPackageName.substring(strPackageName.lastIndexOf(".") + 1);
			}

			if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) && checkAvailableStorage()) {
				// TODO 区分手机与机顶盒。手机根目录为sdcard，盒子也许不是这个名称
				CACHE_HOME_PATH = Environment.getExternalStorageDirectory().getPath() + File.separator + strPackageName; // 如果SD卡可用，默认缓存文件夹为sdcard下的应用名称
			} else { // SD卡不可用
				if (new File("data/data").canRead()) {// 如果data/data/可读，默认缓存文件夹为data/data/com.m1905.tv/cache
					CACHE_HOME_PATH = context.getCacheDir().getAbsolutePath() + "/";
				} else if (new File("system/app").canRead()) {// 否则判断system是否可读，设置默认缓存文件夹
					CACHE_HOME_PATH = "system/app/" + strPackageName;
				}
			}
		}
		return CACHE_HOME_PATH;
	}

	/**
	 * @return
	 * @WZL wzl200711402@163.com @2013-1-6@上午11:10:13
	 * @description sdcard 剩余容量是否可用
	 */
	public static boolean checkAvailableStorage() {
		if (getAvailableStorage() < LOW_STORAGE_THRESHOLD) {
			MLog.e("checkAvailableStorage", "no available storage");
			return false;
		}
		return true;
	}

	/**
	 * @return
	 * @WZL wzl200711402@163.com @2013-1-6@上午11:09:43
	 * @description 获得sdcard剩余容量
	 */
	public static long getAvailableStorage() {
		String storageDirectory = null;
		storageDirectory = Environment.getExternalStorageDirectory().toString();
		long avaliableSize;
		try {
			StatFs stat = new StatFs(storageDirectory);
			avaliableSize = ((long) stat.getAvailableBlocks() * (long) stat.getBlockSize());
			return avaliableSize;
		} catch (RuntimeException ex) {
			// if we can't stat the filesystem then we don't know how many
			// free bytes exist. It might be zero but just leave it
			// blank since we really don't know.
			return 0;
		}
	}

	/**
	 * 
	 * @WZL wzl200711402@163.com @2012-7-27@下午02:03:05
	 * @description 初始化文件缓存文件夹
	 */
	private void initCacheFile() {
		String cacheHomePath = getCACHE_HOME_PATH();
		MLog.e("initCacheFile", "cacheHomePath:" + cacheHomePath);
		File cacheHomeFileDir = new File(cacheHomePath);
		if (!cacheHomeFileDir.exists()) {
			if (!cacheHomeFileDir.mkdir()) {
				MLog.e("initCacheFile", "error!");
				return;
			} else {
				cacheHomeFileDir.mkdirs();
			}
		}

		String cacheImagePath = getCACHE_IMAGE_DIR();
		File cacheImageFileDir = new File(cacheImagePath);
		if (!cacheImageFileDir.exists()) {
			cacheImageFileDir.mkdirs();
		}
		String cacheApkPath = getCACHE_APK_DIR();
		File cacheApkFileDir = new File(cacheApkPath);
		if (!cacheApkFileDir.exists()) {
			cacheApkFileDir.mkdirs();
		}
		String cacheDataFilePath = getCACHE_DATA_DIR();
		File cacheDataFileDir = new File(cacheDataFilePath);
		if (!cacheDataFileDir.exists()) {
			cacheDataFileDir.mkdirs();
		}
		MLog.e("initCacheFile", "ok!");
		deleteExpiredFileCache();
	}

	/**
	 * @return
	 * @WZL wzl200711402@163.com @2013-1-6@上午11:16:09
	 * @description 获得图片的缓存根目录
	 */
	public static String getCACHE_IMAGE_DIR() {
		return getCACHE_HOME_PATH() + CACHE_IMAGE_DIR;
	}

	public static String getCACHE_IMAGE_RELATIVE_PATH() {
		String strPackageName = context.getPackageName();
		if (strPackageName.contains(".")) {
			strPackageName = strPackageName.substring(strPackageName.lastIndexOf(".") + 1);
		}
		return strPackageName + File.separator + CACHE_IMAGE_DIR;
	}

	/**
	 * @return
	 * @WZL wzl200711402@163.com @2013-1-6@上午11:16:09
	 * @description 获得Apk的缓存根目录
	 */
	public static String getCACHE_APK_DIR() {
		return getCACHE_HOME_PATH() + CACHE_APK_DIR;
	}

	/**
	 * @description:TODO获得file的缓存根目录
	 * @FileName NetManager.java
	 * @params @return
	 * @return String
	 * @user wzl email:wzl200711402@163.com
	 * @date 2013-4-11
	 */
	public static String getCACHE_DATA_DIR() {
		return getCACHE_HOME_PATH() + CACHE_DATA_DIR;
	}

	/**
	 * 删除缓存文件 如果文件时间超过10天(864000000毫秒)则删除
	 */
	private void deleteExpiredFileCache() {
		long current = System.currentTimeMillis();
		File cacheDir = new File(getCACHE_HOME_PATH());
		if (cacheDir.exists() && cacheDir.isDirectory()) {
			File[] caches = cacheDir.listFiles();
			for (File f : caches) {
				if ((current - f.lastModified()) > FILE_EXPIRED_TIME) {
					f.delete();
				}
			}
		}
	}
}
